//
//  LTStethoscopeSDK.m
//  hc21SDK
//
//  Created by lanzhongping on 2021/1/6.
//

#import "CARingSDK.h"
#import "CABleDiscovery.h"
#import "CABLeService.h"
#import "CAOtaManager.h"
#import "CAPacket.h"
#import "CADeviceInfo.h"
#include "oem_auth.h"
#import "CAsDKTool.h"
#import <CommonCrypto/CommonCrypto.h>

NSString * const CADEF_COMPANY = @"Linktop";

@interface CARingSDK()<STLeDiscoveryDelegate, StLeKeyFobProtocol>

@property(strong, nonatomic)CAOtaManager *otaManager;

@property(strong, nonatomic)NSMutableArray<NSString *> * aesCompanyArray; // 认证厂家码
@property(assign, nonatomic)int currentCmpIdx; // 当前在第几个厂家码索引
@property(strong, nonatomic)NSData *cacheR1;
@property(strong, nonatomic)CAEcgParamObj *ecgParamObj;

@property(strong, nonatomic)CABLeService *currentPerphelServc;


@end

@implementation CARingSDK
{
    NSString *_key, *_secret;
}

+(instancetype)instance
{
    static CARingSDK *this = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        this = [[CARingSDK alloc] init];
    });
    return this;
}

- (instancetype)init
{
    self = [super init];
    if (self) {
       
    }
    return self;
}

-(void)registECGKey:(NSString *)key Secret:(NSString *)secret
{
    _key = key;//@"2901f7613ac7403e9c5fbc0248b6d94f";
    _secret = secret;//@"ad58bea443d04368beb847510a37a99d";
}
-(BOOL)hasECGKeyAndSecret
{
    return _key.length && _secret.length;
    
}


-(void)setCurrentPeripheralService:(CABLeService* _Nullable)peripheralService;
{
    
    [self.currentPerphelServc setPerpheralDelegate:nil];
    
    self.currentPerphelServc = peripheralService;
    
    DebugNSLog(@"传入service %@ %@", self.currentPerphelServc.perpheralDelegate, [CABleDiscovery sharedInstance].peripheralDelegate);
    
    if (self.currentPerphelServc &&
        self.currentPerphelServc.perpheralDelegate != [CABleDiscovery sharedInstance].peripheralDelegate)
    {
        // 代理不同 说明从外部扫描传入
        [self.currentPerphelServc setPerpheralDelegate:[CABleDiscovery sharedInstance].peripheralDelegate];
        [self.currentPerphelServc start];
    }
    
    [[CABleDiscovery sharedInstance] ousideSetCurrentService:self.currentPerphelServc];// 从外部扫描传入
    
//    self.accountName = account;
//    self.cacheDbSleepArray = nil;
}

-(void)registWithCompanyArray:(NSArray<NSString *>  * _Nullable )cpArray {
    
    
    [[CABleDiscovery sharedInstance]regist];
    [[CABleDiscovery sharedInstance] setDiscoveryDelegate:self];
    [[CABleDiscovery sharedInstance] setPeripheralDelegate:self];
    
    self.aesCompanyArray = [NSMutableArray new];
    [self.aesCompanyArray addObjectsFromArray:cpArray];
    
    if (![self.aesCompanyArray containsObject:CADEF_COMPANY]) {
        [self.aesCompanyArray addObject:CADEF_COMPANY];
    }
    
}

-(void)setBroadCastAnalyCids:(NSArray<NSArray<NSNumber *> *> *)cidArray
{
    [CABleDiscovery sharedInstance].cidArray = cidArray;
}

-(NSArray<NSArray<NSNumber *> * > *)broadCastAnalyCids
{
    return  [CABleDiscovery sharedInstance].cidArray;
}

-(void)setBleOtaDelegate:(id<CAOTAProtocal>)bleOtaDelegate
{
    _bleOtaDelegate = bleOtaDelegate;
    self.otaManager.bleOtaDelegate = _bleOtaDelegate;
}

//- (CBManagerState)deviceBleCenterState {
//    
//    return [[SRBleDiscovery sharedInstance] deviceBleCenterState];
//}

-(void)startBleScanWithOption:(NSDictionary * _Nullable)option
{
    
    [[CABleDiscovery sharedInstance] startScanning:LEDISCOVERY_SCANTYPE_LISTCHOOSE ScanOption:option];
}

-(void)stopBleScan
{
    [[CABleDiscovery sharedInstance] stopScanning];
}

-(void)connectDevice:(CABLeService *)device {
    if (device) {
        [[CABleDiscovery sharedInstance] connectPeripheral:device];
    }
}
-(void)disconnectCurrentService {
    self.currentCmpIdx = 0;
    self.cacheR1 = nil;
    [[CABleDiscovery sharedInstance] disconnectPeripheral:[[CABleDiscovery sharedInstance] currentService]];
    // 直接回调disconnect
    if ([self.bleDataDelegate respondsToSelector:@selector(caBleDidDisconnectPeripheral:)]) {
        [self.bleDataDelegate caBleDidDisconnectPeripheral:[[CABleDiscovery sharedInstance] currentService]];
    }
    
}



- (CBManagerState)bleCenterManagerState {
    return [[CABleDiscovery sharedInstance] deviceBleCenterState];

}

/// 获取心率血氧开关
/// @param isStart isStart = NO 关闭  isStart = yes 开启
-(void)functionOxygenAndHrvBoth:(BOOL)both IsOpen:(BOOL)isStart {
    
    [[[CABleDiscovery sharedInstance] currentService] deviceOxygenAndHrvBoth:both IsOpen:isStart];
}

/// send cmd to power off device
-(void)functionShutDownDevice {
    [[[CABleDiscovery sharedInstance] currentService] cmdDeviceShutDown];
}


/// send cmd to reboot device
-(void)functionRebootDevice {
    [[[CABleDiscovery sharedInstance] currentService] cmdDeviceReboot];
}

-(CABLeService *)currentDevice {
    return  [[CABleDiscovery sharedInstance] currentService];
}

/// get device's battery
-(void)functionGetDeviceBattery {
    return  [[[CABleDiscovery sharedInstance] currentService] cmdDeviceBattery];
    
}

/// get steps
-(void)functionGetStepsOnce
{

    [[[CABleDiscovery sharedInstance] currentService] cmdGetSteps];
}


/// get skin temperature
-(void)functionGetTemperatureOnce
{
    [[[CABleDiscovery sharedInstance] currentService] cmdGetTemperature];
}


/// device reset to factory status
-(void)functionDeviceReset
{
    [[[CABleDiscovery sharedInstance] currentService] cmdFactoryReset];
}

-(void)functionGetDeviceSN {
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_global_queue(0, 0), ^{
        [[[CABleDiscovery sharedInstance] currentService] cmdSn];

    });
    
}

-(void)functionGetDeviceInfo {
    // 设备信息
    [[[CABleDiscovery sharedInstance] currentService] cmdDevInfo];

}

// 设置血氧测量
//-(BOOL)functionSettingOxygenMeasure:(NSUInteger)startHor StartMin:(NSUInteger)startMin StartSec:(NSUInteger)startSecond Endhor:(NSUInteger)endHor EndMin:(NSUInteger)endMin EndSec:(NSUInteger)endSec Interval:(NSUInteger)interval IsOn:(BOOL)isOn {
//    
//    return [[[SRBleDiscovery sharedInstance] currentService] cmdSettingOxygenMeasure:startHor StartMin:startMin StartSec:startSecond Endhor:endHor EndMin:endMin EndSec:endSec Interval:interval IsOn:isOn];
//}

//-(void)functionSettingHeartRateMeasurInterval:(NSUInteger)hrInterval SkinTemperatureInterval:(NSUInteger)skinTemperatureInterval IsOn:(BOOL)isOn {
//    [[[SRBleDiscovery sharedInstance] currentService] cmdSettingHeartRateMeasurInterval:hrInterval SkinTemperatureInterval:skinTemperatureInterval IsOn:isOn];
//    return;
//}

-(void)functionSettingSportMode:(NSUInteger)startHor StartMin:(NSUInteger)startMin
                       StartSec:(NSUInteger)startSecond Endhor:(NSUInteger)endHor
                         EndMin:(NSUInteger)endMin EndSec:(NSUInteger)endSec
                     HrIntreval:(NSUInteger)hrInterval SkinTemperatureInterval:(NSUInteger)skinTemperatureInterval
                       BloodOxygenInterval:(NSUInteger)oxygeninterval
                           IsOn:(BOOL)isOn
{
//    [[[SRBleDiscovery sharedInstance] currentService] cmdSettingSportMode:startHor StartMin:startMin
//                                                              StartSec:startSecond Endhor:endHor
//                                                                EndMin:endMin EndSec:endSec
//                                                            HrIntreval:hrInterval SkinTemperatureInterval:skinTemperatureInterval
//                                                              BloodOxygenInterval:oxygeninterval
//                                                                  IsOn:isOn];
//    return;
    
}

/// get device's cache history data
/// retrun YES = cmd send successful  retrun NO = the last history data process is translating
-(BOOL)functionGetHistoryData {
    // 检查上一次历史数据传输是否完成
    if ([[CABleDiscovery sharedInstance] currentService].packetObj.isTranslatingHistory) {
        return NO;
    }
    
    // 下发获取历史个数指令
    [[[CABleDiscovery sharedInstance] currentService] cmdHistoryCount];
    
    return  YES;
}

-(void)functionRsetTranslatingHistoryState
{
    [CABleDiscovery.sharedInstance.currentService.packetObj resetTranslatingHistoryState];

}

-(void)functionGetHistoryDataOnlyData {
    // 开始获取历史数据
    [[[CABleDiscovery sharedInstance] currentService] cmdHistoryData];
}

-(void)functionSetBindeDevice:(BOOL)bind {
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_global_queue(0, 0), ^{
        [[[CABleDiscovery sharedInstance] currentService] cmdBindeDevice:bind];
    });
  
}
// cmdOEMSwitch
-(void)functionSetOEMAuthSwitch:(BOOL)on
{
    
    // OEM 开关
    [[[CABleDiscovery sharedInstance] currentService] cmdOEMSwitch:on];
  
}

//-(void)functionSetSosDoubleTapTimes:(uint8_t)doubleTapTimes
//    SingleTapInterval:(SOS_DOUBLESLAP_INTERVAL_TYPE)singleTapInterval TapDetectionThreshold:(uint8_t)tapDetectionThreshold
//           DoubleTapEffectStartTime:(uint8_t)doubleTapEffectStartTime DoubleTapEffectEndTime:(uint8_t)doubleTapEffectEndTime Open:(BOOL)sosOpen
//{
//    [[[SRBleDiscovery sharedInstance] currentService] cmdSOSSettingDoubleTapTimes:doubleTapTimes
//                                                                
//                                                                SingleTapInterval:singleTapInterval
//                                                            TapDetectionThreshold:tapDetectionThreshold
//                                                                       
//                                                         DoubleTapEffectStartTime:doubleTapEffectStartTime
//                                                           DoubleTapEffectEndTime:doubleTapEffectEndTime
//                                                                             Open:(BOOL)sosOpen];
//    
//    
//}


/// Clear all history 1 caches of the ring
-(void)functionClearDeviceHistoryCache
{
    [[[CABleDiscovery sharedInstance] currentService] cmdClearHistory];
}

/// 开启运动模式
/// @param durationMinutes 持续时间 单位:分钟 范围(5min - 180min)
-(void)functionStartSportMode:(uint16_t)durationMinutes ValueInterval:(uint16_t)valueInterval WorkType:(CA_WORKOUT_TYPE)wkType
{
    
    [[[CABleDiscovery sharedInstance] currentService] cmdSportMode:YES ValueINterval:valueInterval Duration:durationMinutes WorkType:wkType];

}


/// 手动关闭运动模式
-(void)functionShutdownSportMode {
    
    [[[CABleDiscovery sharedInstance] currentService] cmdSportMode:NO ValueINterval:10 Duration:5 WorkType:0];

}

-(void)functionGetDeviceMeasureDuration
{
    // 下发获取每次测量时长
    [[[CABleDiscovery sharedInstance] currentService] cmdGetDevInfoFive];
    
}

-(void)functionSetDeviceMeasureDuration:(NSInteger)duration
{
    [[[CABleDiscovery sharedInstance] currentService] cmdSetMeasureDuration:duration];

}
// 血糖的ppg测量
//-(void)functionTurnGlucosePPgMeasure:(BOOL)on
//{
//    [[[CABleDiscovery sharedInstance] currentService] cmdLedMeasure:on LedColor:0 AutoAdjBri:YES Current:0 SampleRate:2];
//}

// 血糖的ppg测量, 开放参数
-(void)functionLedMeasure:(BOOL)on LedColor:(uint8_t)ledColor AutoAdjBri:(BOOL)autoAdjBri Current:(uint8_t)current SampleRate:(uint8_t)sampleRate
{
    [[[CABleDiscovery sharedInstance] currentService] cmdLedMeasure:on LedColor:ledColor AutoAdjBri:autoAdjBri Current:current SampleRate:sampleRate];

}

/// ecg测量
/// - Parameter on: YES 开 NO 关
/// - Parameter isRowWave:  NO = Output the data calculated by the algorithm, YES =Output raw data
-(BOOL)functionECGMeasure:(BOOL)on Param:(CAEcgParamObj * _Nullable)paramObj DispSrc:(BOOL)isRowWave
{
    
    if(on && !paramObj) {
        return NO;
    }
    
    if (on) {
        self.ecgParamObj = paramObj;
        if (!isRowWave) {
            self.ecgParamObj.disp_src = DISP_SRC_2;// 设备算结果,上报原始波形
        } else {
            self.ecgParamObj.disp_src = DISP_SRC_0;// 设备不算结果,上报原始波形

        }
    }
    
    uint16_t sampleRate = 0; // 采样率
    if (paramObj.clockSource == CA_ECG_CLOCK_SRC_32768) {
        sampleRate = paramObj.sampleRateWhenSrc32768;
    }
    if (paramObj.clockSource == CA_ECG_CLOCK_SRC_32000) {
        sampleRate = paramObj.sampleRateWhenSrc32000;
    }
    uint8_t clockSource = paramObj.clockSource; // 内部时钟
    uint8_t ecgPgaGain = paramObj.ecgPgaGainIdx; // 增益
    if (!paramObj) {
         sampleRate = 512; // 采样率
         clockSource = CA_ECG_CLOCK_SRC_32768; // 内部时钟
         ecgPgaGain = CA_ECG_PGA_GAIN_2; // 增益
    }
    
    
    [[[CABleDiscovery sharedInstance] currentService] cmdECGMeasure:on SampleRate:sampleRate  InnerClockSource:clockSource EcgPgaGain:ecgPgaGain DispSrc:self.ecgParamObj.disp_src];

    return YES;
}

/// ecg和ppg同时测量
/// - Parameter on: YES 开 NO 关
-(void)functionEcgAndPpgMeasure:(BOOL)on
{
    [[[CABleDiscovery sharedInstance] currentService] cmdEcgAndPpgMeasure:on];

}


/// 设置计步阈值
/// - Parameter threshold:  计步阈值范围为：0x0-0x3F
//-(void)functionSetStepCountingThreshold:(uint8_t)threshold
//{
//    [[[SRBleDiscovery sharedInstance] currentService] cmdSetStepCountingThreshold:threshold];
//
//}

-(void)functionSyncTime:(NSDate *)date
{
    [[[CABleDiscovery sharedInstance] currentService] cmdTimeSync:date];

}

#pragma mark -- constants
-(NSString *)netKey
{
    return _key;
}

-(NSString *)netSecret
{
    return _secret;

}

-(NSString *)signStringWith:(NSString *)sn MacAddr:(NSString *)mac
{
    if (!sn.length || !mac.length || !_secret.length) {
        return nil;
    }
    
    NSString *sign = [self hmacMD5WithKey:_secret data:[NSString stringWithFormat:@"%@,%@", sn, mac]];
    return sign;
}


- (NSString *)hmacMD5WithKey:(NSString *)key data:(NSString *)data {
    // 将 key 和 data 转换为 C 字符串
    const char *cKey = [key cStringUsingEncoding:NSUTF8StringEncoding];
    const char *cData = [data cStringUsingEncoding:NSUTF8StringEncoding];
    
    // 定义 HMAC 结果数组
    unsigned char cHMAC[CC_MD5_DIGEST_LENGTH];
    
    // 计算 HMAC-MD5
    CCHmac(kCCHmacAlgMD5, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
    
    // 将结果转换为十六进制字符串
    NSMutableString *result = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
    for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
        [result appendFormat:@"%02x", cHMAC[i]];
    }
    
    return result;
}


#pragma mark --CSEM设备使用的方法
/* CSEM */


/// 设置用户信息
/// - Parameters:
///   - gender: Gender: 0 male, 1 female
///   - ageYear: Age: range 1-115
///   - height: Height: in mm, range 1200-3000
///   - weight: Weight: in kg, range 30-200
-(BOOL)functionSetUsrInfoToDev:(NSUInteger)gender
                           Age:(NSUInteger)ageYear
                         Height:(NSUInteger)height
                        Weight:(NSUInteger)weight
{
    
    if (gender > 1) {
        return NO;
    }
    if (ageYear < 1 || ageYear > 115) {
        return NO;
    }
    
    if (height < 1200 || height > 3000) {
        return NO;
    }
    if (weight < 30 || weight > 200) {
        return NO;
    }
    
    return [[[CABleDiscovery sharedInstance] currentService] cmdSetUsrInfoToDev:gender
                                                                     Age:ageYear
                                                                   Height:height
                                                                  Weight:weight];
    
}


/// 修改蓝牙广播名
/// - Parameter name: 广播名. 长度 >0 && 长度 <= 16
-(BOOL)functionModifyBRcastName:(NSString *)name HideMac:(BOOL)hideMac
{
    
    return [[[CABleDiscovery sharedInstance] currentService] cmdModifyBRcastName:name HideMac:hideMac];
    
}

-(BOOL)functionGetUsrInfoFromDev
{
    return [[[CABleDiscovery sharedInstance] currentService] cmdGetUsrInfoToDev];
}


/// 获取最新活动
-(BOOL)functionGetLastActivity {
    
    return [[[CABleDiscovery sharedInstance] currentService] cmdGetLastActivity];

}

/// 获取最新活动2
-(BOOL)functionGetLastActivity_2
{
    
    return [[[CABleDiscovery sharedInstance] currentService] cmdGetLastActivity_2];

}

/// Clear activity history(history 2) data.(清空活动历史数据)
-(BOOL)functionCleanActivityHistory
{
    return [[[CABleDiscovery sharedInstance] currentService] cmdCleanActivityHistory];

}

/// Get the number of activity detection/swimming/sleep history data (获取活动检测/游泳/睡眠历史数据数量)
/// Callback interface:"caBleHisCntOfActivityAndSwimAndSleep:MinUUid:MaxUUid:"
-(BOOL)functionGetHistoryCntOfActvtyDtctAndSwimAndSleepHisty
{
    return [[[CABleDiscovery sharedInstance] currentService] cmdGetHistoryCntOfActvtyDtctnAndSwimAndSlepHist];

}


///
-(BOOL)functionGetHstryDataOfActvtyDetectAndSwimAndSlep
{
    return [[CABleDiscovery sharedInstance].currentService  cmdGetHistoryDataOfActvtyDtctnAndSwimAndSlepHistMax:0];
}

-(BOOL)functionGetHstryDataOfActvtyDetectAndSwimAndSlepMaxUUid:(uint32_t)maxUUid
{
    return [[CABleDiscovery sharedInstance].currentService  cmdGetHistoryDataOfActvtyDtctnAndSwimAndSlepHistMax:maxUUid];
}

/// Set the measurement interval and duration of the CSEM device(设置CSEM设备测量间隔和时长)
/// - Parameters:
///   - meaType: 0-Heart rate/HRV/respiration rate/temperature measurement 1-Blood oxygen measurement (测量类型 0-心率/HRV/呼吸率/温度测量 1-血氧测量)
///   - meaduraNoSleep: The measured duration of the non-sleep period(非睡眠时间段的测量时长)
///   - meaIntervNoSleep: Measurement interval during non-sleep period(非睡眠时间段的测量间隔时长)
///   - meaduraInSleep: Measured duration of sleep periods(睡眠时间段的测量时长)
///   - meaIntervInSleep: Measurement interval during sleep(睡眠期间的测量间隔)
-(BOOL)functionSetNalgDevMeaDuration:(CACS_DEV_MEA_DURA_AND_TM_TYPE)meaType MeaDuraofNoSlepPerd:(uint32_t)meaduraNoSleep
               MeaIntervOfNoSlepPerd:(uint32_t)meaIntervNoSleep MeaDuraofInSlepPerd:(uint32_t)meaduraInSleep MeaIntervInNoSlepPerd:(uint32_t)meaIntervInSleep
{
    return [[CABleDiscovery sharedInstance].currentService cmdSetCsemMea:meaType IsSet:YES DuraNoSleep:meaduraNoSleep IntervNosleep:meaIntervNoSleep DuraInSleep:meaduraInSleep IntervInsleep:meaIntervInSleep];
    
}



/// Get the measurement interval and duration of the CSEM device
/// - Parameters:
/// - meaType: Measurement type 0-heart rate/HRV/respiration rate/temperature measurement 1-blood oxygen measurement.(测量类型 0-心率/HRV/呼吸率/温度测量 1-血氧测量)
-(BOOL)functionGetNalgDevMeaDuration:(CACS_DEV_MEA_DURA_AND_TM_TYPE)meaType
{
    // 获取
    return [[CABleDiscovery sharedInstance].currentService cmdSetCsemMea:meaType IsSet:NO DuraNoSleep:0 IntervNosleep:0 DuraInSleep:0 IntervInsleep:0];
    
}


-(BOOL)functionStartCSEMexerciseWithType:(NALG_EXERCISE_TYPE)execType 
                                PoolSize:(CA_NALG_SWIM_POOL_SIZE)sizeType
                HeartrateStorageInterval:(uint16_t)hrStoreInterv
                            DurationMins:(uint16_t)duraMins
{
    // PACK_CMD_FUNCTIN_START_CSEM_EXER
    return [[CABleDiscovery sharedInstance].currentService cmdSetCSEMexercise:CAEX_START ExerciseType:execType PoolSize:sizeType HeartrateStorageInterval:hrStoreInterv DurationMins:duraMins];
    
}

-(BOOL)functionStartNalgExerciseWithType:(NALG_EXERCISE_TYPE)execType
                                PoolSize:(CA_NALG_SWIM_POOL_SIZE)sizeType
                            DurationMins:(uint16_t)duraMins
{
    uint16_t hrStoreInterv = 10;
    // PACK_CMD_FUNCTIN_START_CSEM_EXER
    return [[CABleDiscovery sharedInstance].currentService cmdSetCSEMexercise:CAEX_START ExerciseType:execType PoolSize:sizeType HeartrateStorageInterval:hrStoreInterv DurationMins:duraMins];
    
}


// 恢复锻炼状态
-(BOOL)functionContinueNalgExercise 
{
    // PACK_CMD_FUNCTIN_START_CSEM_EXER
    return [[CABleDiscovery sharedInstance].currentService cmdSetCSEMexercise:CAEX_CONTINUE ExerciseType:0 PoolSize:0 HeartrateStorageInterval:0 DurationMins:0];
    
}

// 暂停锻炼
-(BOOL)functionPauseNalgExercise 
{
    return [[CABleDiscovery sharedInstance].currentService cmdSetCSEMexercise:CAEX_PAUSE ExerciseType:0 PoolSize:0 HeartrateStorageInterval:0 DurationMins:0];
}

-(BOOL)functionStopNalgExercise 
{
    return [[CABleDiscovery sharedInstance].currentService cmdSetCSEMexercise:CAEX_STOP ExerciseType:0 PoolSize:0 HeartrateStorageInterval:0 DurationMins:0];

}


/// Switch to report activity data during exercise(实时上报锻炼期间的活动数据的开关)
/// - Parameter on: YES=turn on NO = off
-(BOOL)functionNalgRealtimeReportDurinExerciseSwitch:(BOOL)on
{
    return [[CABleDiscovery sharedInstance].currentService cmdSetCSEMexerciseRealReportSwitch:on];
}


/// 设置戒指算法
/// - Parameter algorithmType: 0-本地算法、1-三方算法
-(BOOL)functionNalgSetDeviceAlgorithm:(uint8_t)algorithmType
{
    // PACK_CMD_FUNCTIN_CSEM_DEVICE_ALGORITHM
    return [[CABleDiscovery sharedInstance].currentService cmdDeviceAlgorithm:YES Type:algorithmType];
}

-(BOOL)functionNalgGetDeviceAlgorithm
{
    return [[CABleDiscovery sharedInstance].currentService cmdDeviceAlgorithm:NO Type:0];

}

/* CSEM */

#pragma mark -- STLeDiscoveryDelegate

/// 扫描刷新 清除所有发现设备,连接过的设备, 断开已连接设备
- (void)stdiscoveryDidRefresh:(NSArray<CABLeService *>*)perphelArray {
    
    if ([self.blescanDelegate respondsToSelector:@selector(caScanDeviceDidRefresh:)]) {
        [self.blescanDelegate caScanDeviceDidRefresh:perphelArray];
    }
    
}

// 手机蓝牙开启关闭回调
- (void)stdiscoveryStatePoweredState:(CBManagerState)state {
    if ([self.blescanDelegate respondsToSelector:@selector(caBlePowerStateChange:)]) {
        [self.blescanDelegate caBlePowerStateChange:state];
    }
}



- (void)stconnectPeripheralTimeout:(CABLeService*)keyService {
    
}

- (void)stdidRetrievePeripherals:(NSArray *)peripherals {
    
}




#pragma mark -- StLeKeyFobProtocol


- (void) stkeyFobServiceDidChangeStatus:(CABLeService*)service {
    
}
- (void) stkeyFobServiceDidConnectPeripheral:(CABLeService*)service {
    
//    service.recordDealDelegate = self; // 获取录音回调
    
    if ([self.bleDataDelegate respondsToSelector:@selector(caBleDidConnectPeripheral:)]) {
        [self.bleDataDelegate caBleDidConnectPeripheral:service];
    }
}

-(void)stkeyFobServiceDidFailConnectPeripheral:(CBPeripheral *)peripheral Error:(NSError *)error
{
    // 连接失败
    if ([self.bleDataDelegate respondsToSelector:@selector(caBleFailConnectPeripheral:Error:)]) {
        [self.bleDataDelegate caBleFailConnectPeripheral:peripheral Error:error];
    }
}

- (void) stkeyFobServiceDidDisconnectPeripheral:(CABLeService*)service {
    self.currentCmpIdx = 0; // 厂家码重置
    self.cacheR1 = nil;
//    service.recordDealDelegate = nil;
    if ([self.bleDataDelegate respondsToSelector:@selector(caBleDidDisconnectPeripheral:)]) {
        [self.bleDataDelegate caBleDidDisconnectPeripheral:service];
    }
    
}
- (void) stkeyFobServiceDidReadRSSI:(CABLeService*)service {
    
}
- (void) stkeyFobServiceDidReset {
    
}

- (void)stkeyFobServiceBatteryReady {
    // 电池服务完成
}


- (void)stkeyFobServiceDidReadyForReadWrite:(CABLeService *)service {
    // 同步时间

    [self functionSyncTime:[NSDate date]];
    // 读写服务准备完成
    if ([self.bleDataDelegate respondsToSelector:@selector(caBleDeviceDidReadyForReadAndWrite:)]) {
        [self.bleDataDelegate caBleDeviceDidReadyForReadAndWrite:service];
    }
    
    
}

// 回调设备信息
- (void)stkeyFobServiceDeviceInfo:(CADeviceInfo *)devInfo
{
    self.currentDevice.needOemAuth = devInfo.needOemAuth; // 标记是否需要厂家认证
    DebugNSLog(@"OEM认证开关 %d", devInfo.needOemAuth);
    self.currentDevice.isSupportSportMode = devInfo.supportSportmode;
    self.currentDevice.chargeType = @(devInfo.chargeType);
    self.currentDevice.isSupportEcg = devInfo.supportEcg;
    self.currentDevice.projectId = devInfo.projectId;
    if ([self.bleDataDelegate respondsToSelector:@selector(caBleDeviceInfo:)]) {
        [self.bleDataDelegate caBleDeviceInfo:devInfo];
    }
    
}

/// 实时计步
/// @param steps 计步
- (void)stkeyFobServiceRealtimeSteps:(NSNumber *)steps IsDeviceFix:(BOOL)isDeviceFixed {
    if ([self.bleDataDelegate respondsToSelector:@selector(caBleDeviceRealtimeSteps:IsDeviceFix:)]) {
        [self.bleDataDelegate caBleDeviceRealtimeSteps:steps IsDeviceFix:isDeviceFixed];
    }
    
}


/// 实时体温
/// @param temperature 体温
- (void)stkeyFobServiceRealtimeTemperaure:(NSNumber *)temperature {
    if ([self.bleDataDelegate respondsToSelector:@selector(caBleDeviceRealtimeTemperature:)]) {
        [self.bleDataDelegate caBleDeviceRealtimeTemperature:temperature];
    }
}

/// 电量回调
/// @param batteryLevel 电量
/// @param isCharging 是否充电
- (void) stkeyFobServiceBatteryLevel:(NSInteger)batteryLevel IsCharging:(BOOL)isCharging Voltage:(float)vol
{
    self.currentDevice.isCharging = isCharging;
    // caBleDeviceBatteryLevel
    if ([self.bleDataDelegate respondsToSelector:@selector(caBleDeviceBatteryLevel:IsCharging:)]) {
        [self.bleDataDelegate caBleDeviceBatteryLevel:batteryLevel IsCharging:isCharging];
    }

//    if ([self.bleDataDelegate respondsToSelector:@selector(caBleDeviceBatteryLevel:IsCharging: Voltage:)]) {
//        [self.bleDataDelegate caBleDeviceBatteryLevel:batteryLevel IsCharging:isCharging Voltage:vol];
//    }
    
}


- (void)stkeyFobServiceRealtimeHRV:(NSNumber *)hrv BloodOxygen:(NSNumber *)bloodOxygen HeartRate:(NSNumber *)hr Status:(REALTIME_STATUS)status {
    if ([self.bleDataDelegate respondsToSelector:@selector(caBleRealtimeHRV:BloodOxygen:HeartRate:Status:) ]) {
        [self.bleDataDelegate caBleRealtimeHRV:hrv BloodOxygen:bloodOxygen HeartRate:hr Status:status];
    }
}

-(void)stkeyFobServiceSN:(NSString *)sn OriginSNData:(NSData *)sndata
{
    // sn 回调
    if ([self.bleDataDelegate respondsToSelector:@selector(caBleSN:SnData:) ]) {
        [self.bleDataDelegate caBleSN:sn SnData:sndata];
    }
    
    // 开始OEM认证
    self.currentDevice.authSnData = sndata;
    self.currentDevice.snString = sn;
//    if (!self.currentDevice.needOemAuth) { // 无需认证
//        // 回调完成
//
//        return;
//    }
//    else
//    {
        // 是否已认证过,重复获取sn而已
    if (!self.currentDevice.hasBeenAuth && self.currentDevice.needOemAuth) {
        [[[CABleDiscovery sharedInstance] currentService] cmdStartOemAuth];
    }
//    }
    
    
    
}

// 历史数据
- (void) stkeyFobServiceHistoryData:(CAHistoryData *)hisData IsComplete:(BOOL)isComplete {
    // sn 回调
//    if ([self.bleDataDelegate respondsToSelector:@selector(srBleHistoryData:IsComplete:) ]) {
//        [self.bleDataDelegate srBleHistoryData:hisData IsComplete:isComplete];
//    }
    
//    if (isComplete) {
//        // 清空设备历史数据
//        [[[SRBleDiscovery sharedInstance] currentService] cmdClearHistory];
//
//    }
    
}

-(void)stkeyFobServiceHistorySR03Data:(CAHistoryDataSR03 * _Nullable)sr03HisData IsComplete:(BOOL)isComplete
{
    // srBleHistorySr03Data
    if ([self.bleDataDelegate respondsToSelector:@selector(caBleHistorySr03Data:IsComplete:) ]) {
        [self.bleDataDelegate caBleHistorySr03Data:sr03HisData IsComplete:isComplete];
    }
}


/// 执行命令情况
/// @param cmd 下发的命令
/// @param isSuccess YES = 执行成功
- (void) stkeyFobServiceSendCmdExcute:(uint8_t)cmd Succ:(BOOL)isSuccess Reason:(CA_CMD_EXECTE_ERROR_REASON)reason Data:(NSData *)originData {
    
    if ([self.bleDataDelegate respondsToSelector:@selector(caBleCmdExcute:Succ:Reason:Data:) ]) {
        [self.bleDataDelegate caBleCmdExcute:cmd Succ:isSuccess Reason:reason Data:originData];
    }
}

- (void) stkeyFobService:(BOOL)isSosOpen
          DoubleTapTimes:(uint8_t)doubleTapTimes
       SingleTapInterval:(uint8_t)singleTapInterval TapDetectionThreshold:(uint8_t)tapDetectionThreshold
DoubleTapEffectStartTime:(uint8_t)doubleTapEffectStartTime DoubleTapEffectEndTime:(uint8_t)doubleTapEffectEndTime Isbinded:(BOOL)isBinded
{
    self.currentDevice.isBinded = isBinded;
    
//    if ([self.bleDataDelegate respondsToSelector:@selector(srBleOtherInfo:DoubleTapTimes:SingleTapInterval:TapDetectionThreshold:DoubleTapEffectStartTime:DoubleTapEffectEndTime:Isbinded:) ])
//    {
//        [self.bleDataDelegate srBleOtherInfo:isSosOpen DoubleTapTimes:doubleTapTimes SingleTapInterval:singleTapInterval TapDetectionThreshold:tapDetectionThreshold DoubleTapEffectStartTime:doubleTapEffectStartTime DoubleTapEffectEndTime:doubleTapEffectEndTime Isbinded:isBinded];
//    }
    
    if (!self.currentDevice.needOemAuth && !self.currentDevice.hasBeenAuth) { // 无需认证 && 还没走完认证流程
        [self stkeyFobServiceAESAuthResult:YES];
    }

    
}

-(void)stkeyFobServiceIsBinded:(BOOL)isBinded
{
    if ([self.bleDataDelegate respondsToSelector:@selector(caBleIsBinded:)]) {
        [self.bleDataDelegate caBleIsBinded:isBinded];
    }
}


- (void) stkeyFobServiceSOShappen {
//    if ([self.bleDataDelegate respondsToSelector:@selector(srBleSOShappen) ]) {
//        [self.bleDataDelegate srBleSOShappen];
//    }
    
}

// sos时的测量数据
- (void)stkeyFobServiceSOSData:(float)temperature HeartRate:(NSInteger)hr BloodOxygen:(NSInteger)bloodOxygen
{
    
//    if ([self.bleDataDelegate respondsToSelector:@selector(srBlesSOSData:HeartRate:BloodOxygen:)]) {
//        [self.bleDataDelegate srBlesSOSData:temperature HeartRate:hr BloodOxygen:bloodOxygen];
//    }
    
}

- (void) stkeyFobServiceHistoryTimeout {
    
    if ([self.bleDataDelegate respondsToSelector:@selector(caBleHistoryDataTimeout) ]) {
        [self.bleDataDelegate caBleHistoryDataTimeout];
    }
}

- (void) stkeyFobServiceHistoryCount:(NSInteger)count {
    
    if ([self.bleDataDelegate respondsToSelector:@selector(caBleHistoryDataCount:) ]) {
        [self.bleDataDelegate caBleHistoryDataCount:count];
    }
   
    // 开始获取历史数据
    if (count > 0) {
        [self functionGetHistoryDataOnlyData];
    }
//    [[[SRBleDiscovery sharedInstance] currentService] cmdHistoryData];
}

/// 设备信息5
/// - Parameters:
///   - durations: 心率 体温测量时长
///   - pd_threshold: pd阈值
///   - pd_range_1:pd波动 范围1
///   - pd_range_2: pd采样波动 范围2
-(void)stkeyFobServiceHrMeasuDuration:(NSInteger)durations PD_THRESHOLD:(uint32_t)pd_threshold PD_RANGE_1:(uint32_t)pd_range_1 PD_RANGE_2:(uint32_t)pd_range_2
{
    
    if ([self.bleDataDelegate respondsToSelector:@selector(caBleMeasureDuration:)]) {
        [self.bleDataDelegate caBleMeasureDuration:durations];
    }
    
    
}



-(void)stkeyFobServiceCountThreshold:(uint8_t)threshold
{
    
    if ([self.bleDataDelegate respondsToSelector:@selector(caBleStepCountThreshold:)]) {
        [self.bleDataDelegate caBleStepCountThreshold:threshold];
    }
    
}

-(void)stkeyFobServiceEcg:(CAEcgData *)ecgObj
{
    if ([self.bleDataDelegate respondsToSelector:@selector(caBleEcgWave:)]) {
        [self.bleDataDelegate caBleEcgWave:ecgObj];
    }
    
}

-(void)stkeyFobServiceEcgAndPPg:(CAEcgData *)ecgPpgObj
{
    
    if ([self.bleDataDelegate respondsToSelector:@selector(caBleEcgAndPPgWave:)]) {
        [self.bleDataDelegate caBleEcgAndPPgWave:ecgPpgObj];
    }
}

- (void)stkeyFobServiceEcgResult:(CAEcgAlgorithmResults *)ecgResult
{
    if ([self.bleDataDelegate respondsToSelector:@selector(caBleEcgAlgorithmResult:)]) {
        [self.bleDataDelegate caBleEcgAlgorithmResult:ecgResult];
    }
}
- (void)stkeyFobServiceEcgLeadOn:(BOOL)leadOn
{
    if ([self.bleDataDelegate respondsToSelector:@selector(caBleEcgEcgLeadOn:)]) {
        [self.bleDataDelegate caBleEcgEcgLeadOn:leadOn];
    }
}

-(void)stkeyFobServiceLedPPgDataRep:(NSMutableArray<NSNumber *> *)dataArry
{
    // // 单色led测量数据回调
    if ([self.bleDataDelegate respondsToSelector:@selector(caLedPPgDataRep:)]) {
        [self.bleDataDelegate caLedPPgDataRep:dataArry];
    }
}

-(void)stkeyFobServiceLedStateReport:(BOOL)on Led:(uint8_t)led Current:(uint8_t)current AutoDim:(uint8_t)autoDim Freq:(uint8_t)freq
{
    if ([self.bleDataDelegate respondsToSelector:@selector(caLedStateReport:Led:Current:AutoDim:Freq:)])
    {
        [self.bleDataDelegate caLedStateReport:on Led:led Current:current AutoDim:autoDim Freq:freq];
    }
}

-(void)stkeyFobServicePPGState:(CAPpgMeasureState *)stateObj
{
    if ([self.bleDataDelegate respondsToSelector:@selector(caPPGMeasuState:)])
    {
        [self.bleDataDelegate caPPGMeasuState:stateObj];
    }
}

-(NSString *)sdkVersion {

    return @"1.0.4"; //
}

-(NSString *)sdkReleaseDate
{
    return @"2025-10-10";// 1.0.4
}



#pragma mark --AES
- (void)stkeyFobServiceAESRecvR1:(NSData *)r1
{
    if (self.currentCmpIdx >= self.aesCompanyArray.count) {
        return;
    }
    self.cacheR1 = r1;
    // 解密出原文r2
    NSString *cp = self.aesCompanyArray[self.currentCmpIdx];
    DebugNSLog(@"下发 cmp:%@", cp);
    NSData *r2 = [CAsDKTool oemAesDecreat:self.currentDevice.authSnData Company:cp R1:r1];
    
//    DebugNSLog(@"%@", [[NSString alloc] initWithData:r2 encoding:NSUTF8StringEncoding]);
    //
    [self.currentDevice cmdOEMSendR2:r2]; // 下发R2
    self.currentCmpIdx++;
}

/// 设备上报认证最后结果
/// - Parameter isAuthed: YES = auth pass
- (void)stkeyFobServiceAESAuthResult:(BOOL)isAuthed
{
    
    if (isAuthed) {
        self.currentDevice.hasBeenAuth = YES;
        // 同步时间
        [self functionSyncTime:[NSDate date]];
        if ([self.bleDataDelegate respondsToSelector:@selector(caBleOEMAuthResult:)])
        {
            [self.bleDataDelegate caBleOEMAuthResult:isAuthed];
        }
        return;
    }
    
    if (self.currentCmpIdx < self.aesCompanyArray.count) {
        
        
        if (!isAuthed) {
            [self stkeyFobServiceAESRecvR1:self.cacheR1];
        }
        
        
    } else {
        // 遍历结束 回调
        self.currentDevice.hasBeenAuth = YES;
        // 同步时间
        [self functionSyncTime:[NSDate date]];
        if ([self.bleDataDelegate respondsToSelector:@selector(caBleOEMAuthResult:)])
        {
            [self.bleDataDelegate caBleOEMAuthResult:isAuthed];
        }
    }
    
   
    
}

#pragma mark --CSEM
-(void)stkeyFobServiceUsrInfoFromoDev:(NSUInteger)gender
                Age:(NSUInteger)ageYear
              Height:(NSUInteger)height
             Weight:(NSUInteger)weight
{
    
    if ([self.blescanDelegate respondsToSelector:@selector(caBleUsrInfoFromoDev:Age:Height:Weight:)]) 
    {
        [self.bleDataDelegate caBleUsrInfoFromoDev:gender Age:ageYear Height:height Weight:weight];
    }
    
}

// 上报最后一条活动
-(void)stkeyFobServiceLastActivity:(CAnAlgGrandActivity *)activity
{
    if ([self.blescanDelegate respondsToSelector:@selector(caBleLastActivity:)])
    {
        [self.bleDataDelegate caBleLastActivity:activity];
    }
}

// 上报最后一条活动2
-(void)stkeyFobServiceLastActivity2:(CAnAlgGrandActivity2 *)activity2
{
    if ([self.blescanDelegate respondsToSelector:@selector(caBleLastActivity2:)])
    {
        [self.bleDataDelegate caBleLastActivity2:activity2];
    }
}


-(void)stkeyFobServiceCSEMRealMeasu:(CAnAlgRealMeasure *)realMeasurData
{
    if ([self.blescanDelegate respondsToSelector:@selector(caBleNALGRealMeasu:)])
    {
        [self.bleDataDelegate caBleNALGRealMeasu:realMeasurData];
    }
    
}


-(void)stkeyFobServiceHisCntOfActivityAndSwimAndSleep:(NSUInteger)count MinUUid:(uint32_t)minUUid MaxUUid:(uint32_t)maxUUid
{
    if ([self.blescanDelegate respondsToSelector:@selector(caBleHisCntOfActivityAndSwimAndSleep:MinUUid:MaxUUid:)])
    {
        [self.bleDataDelegate caBleHisCntOfActivityAndSwimAndSleep:count MinUUid:minUUid MaxUUid:maxUUid];
    }
}

-(void)stkeyFobServiceCSEMDevMeaDuration:(CACS_DEV_MEA_DURA_AND_TM_TYPE)meaType
                     MeaDuraofNoSlepPerd:(uint32_t)meaduraNoSleep MeaIntervOfNoSlepPerd:(uint32_t)meaIntervNoSleep
                  MeaDuraofInSlepPerd:(uint32_t)meaduraInSleep MeaIntervInNoSlepPerd:(uint32_t)meaIntervInSleep
{
    if ([self.bleDataDelegate respondsToSelector:@selector(caBleNALGDevMeaDuration:MeaDuraofNoSlepPerd:MeaIntervOfNoSlepPerd:MeaDuraofInSlepPerd:MeaIntervInNoSlepPerd:)])
    {
        [self.bleDataDelegate caBleNALGDevMeaDuration:meaType
                                  MeaDuraofNoSlepPerd:meaduraNoSleep
                                MeaIntervOfNoSlepPerd:meaIntervNoSleep
                                  MeaDuraofInSlepPerd:meaduraInSleep
                                MeaIntervInNoSlepPerd:meaIntervInSleep];
    }
}

-(void)stkeyFobServiceCSEMalgorithmType:(uint8_t)algorithmType
{
    if ([self.bleDataDelegate respondsToSelector:@selector(caBleNALGalgorithmType:)])
    {
        [self.bleDataDelegate caBleNALGalgorithmType:algorithmType];
    }
}

-(void)stkeyFobServiceCsemDeviceMeasurData:(id<CANalgProtocal>)dataObj
{
    if ([self.bleDataDelegate respondsToSelector:@selector(caBleNalgDeviceMeasurHinstoryData:)]) {
        [self.bleDataDelegate caBleNalgDeviceMeasurHinstoryData:dataObj];
    }
    
}

-(void)stkeyFobServiceCsemRealtimeWorkoutData:(CAnAlgRltExerData *)csemExerRltData;
{
    
    if ([self.bleDataDelegate respondsToSelector:@selector(caBleNalgRealtimeWorkoutData:)]) {
        [self.bleDataDelegate caBleNalgRealtimeWorkoutData:csemExerRltData];
    }
}


#pragma mark - OTA
-(void)functionStartOta:(NSURL *)fileUrl {
    self.otaManager = [[CAOtaManager alloc]initWithService:
                       [[CABleDiscovery sharedInstance] currentService] ];
    self.otaManager.bleOtaDelegate = self.bleOtaDelegate;
    [self.otaManager startOta:fileUrl];
    
    
}

-(CAEcgParamObj *)ecgParamObj
{
    return _ecgParamObj;
}


@end
